﻿namespace Standard
{
	using System;
	using System.Diagnostics.CodeAnalysis;
	using System.Runtime.InteropServices;

	internal static partial class Utility
	{
		private static readonly Version _osVersion = Environment.OSVersion.Version;

		[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
		public static void SafeDestroyIcon(ref IntPtr hicon)
		{
			IntPtr p = hicon;
			hicon = IntPtr.Zero;
			if (IntPtr.Zero != p)
			{
				NativeMethods.DestroyIcon(p);
			}
		}

		/// <summary>GDI's DeleteObject</summary>
		[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
		public static void SafeDeleteObject(ref IntPtr gdiObject)
		{
			IntPtr p = gdiObject;
			gdiObject = IntPtr.Zero;
			if (IntPtr.Zero != p)
			{
				NativeMethods.DeleteObject(p);
			}
		}

		[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
		public static void SafeDestroyWindow(ref IntPtr hwnd)
		{
			IntPtr p = hwnd;
			hwnd = IntPtr.Zero;
			if (NativeMethods.IsWindow(p))
			{
				NativeMethods.DestroyWindow(p);
			}
		}

		/// <summary>GDI+'s DisposeImage</summary>
		/// <param name="gdipImage"></param>
		[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
		public static void SafeDisposeImage(ref IntPtr gdipImage)
		{
			IntPtr p = gdipImage;
			gdipImage = IntPtr.Zero;
			if (IntPtr.Zero != p)
			{
				NativeMethods.GdipDisposeImage(p);
			}
		}

		[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
		[SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
		public static void SafeCoTaskMemFree(ref IntPtr ptr)
		{
			IntPtr p = ptr;
			ptr = IntPtr.Zero;
			if (IntPtr.Zero != p)
			{
				Marshal.FreeCoTaskMem(p);
			}
		}

		[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
		[SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
		public static void SafeFreeHGlobal(ref IntPtr hglobal)
		{
			IntPtr p = hglobal;
			hglobal = IntPtr.Zero;
			if (IntPtr.Zero != p)
			{
				Marshal.FreeHGlobal(p);
			}
		}

		[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
		[SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
		public static void SafeRelease<T>(ref T comObject) where T : class
		{
			T t = comObject;
			comObject = default(T);
			if (null != t)
			{
				Assert.IsTrue(Marshal.IsComObject(t));
				Marshal.ReleaseComObject(t);
			}
		}

		[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
		public static bool IsOSVistaOrNewer
		{
			get { return _osVersion >= new Version(6, 0); }
		}

		[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
		public static bool IsOSWindows7OrNewer
		{
			get { return _osVersion >= new Version(6, 1); }
		}

	}
}
